#include "mainwindow.h"
#include "ui_mainwindow.h"

// 窗口初始化
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    createChart();  // 创建图表
    prepareData(); // 生成数据
    updateFromChar(); // 从图表获取数据，刷新界面显示

//    connect(ui->toolBox,&QToolBox::currentChanged,ui->toolBox,[=](int idx){
//        ui->toolBox->setItemEnabled(idx,ui->toolBox->currentWidget()->isEnabled());
//    });

    // 第一个工具栏
    connect(ui->legendFontBtn,&QPushButton::clicked,this,&MainWindow::onLegendFontBtnClicked);
    connect(ui->legendColorBtn,&QPushButton::clicked,this,&MainWindow::onLegendColorBtnClicked);
    connect(ui->setTitleBtn,&QPushButton::clicked,this,&MainWindow::onSetTitleBtnClicked);
    connect(ui->leftRadioBtn,&QRadioButton::clicked,this,&MainWindow::onLeftRadioBtnClicked);
    connect(ui->rightRadioBtn,&QRadioButton::clicked,this,&MainWindow::onRightRadioBtnClicked);
    connect(ui->topRadioBtn,&QRadioButton::clicked,this,&MainWindow::onTopRadioBtnClicked);
    connect(ui->bottomRadioBtn,&QRadioButton::clicked,this,&MainWindow::onBottomRadioBtnClicked);
    connect(ui->backgroundVisiable,&QCheckBox::clicked,this,&MainWindow::onBackgroundVisiableCheck);
    connect(ui->legendVisiable,&QCheckBox::clicked,this,&MainWindow::onLegendVisiableCheck);
    connect(ui->setMarginBtn,&QPushButton::clicked,this,&MainWindow::onSetMarginBtnClicked);
    // 还有动画和主题没设置

    // 第二个工具栏
    connect(ui->ellipseSinRadioBtn,&QRadioButton::clicked,this,&MainWindow::onEllipseSinRadioBtnClicked);
    connect(ui->ellipseCosRadioBtn,&QPushButton::clicked,this,&MainWindow::onEllipseCosRadioBtnClicked);
    connect(ui->seriesVisiable,&QCheckBox::clicked,this,&MainWindow::onSeriesVisiableChecked);
    connect(ui->seriesDataPointVisiable,&QCheckBox::clicked,this,&MainWindow::onSeriesDataPointVisiableChecked);
    connect(ui->dataPointLabVisiable,&QCheckBox::clicked,this,&MainWindow::onDataPointLabVisiableChecked);
    connect(ui->setEllipseColorBtn,&QPushButton::clicked,this,&MainWindow::onSetEllipseColorBtnClicked);
    connect(ui->opacitySlider,&QSlider::valueChanged,this,[=](int value){
        if(curSeries!=nullptr){
            float fvalue = float(value)/100;
            curSeries->setOpacity(fvalue);
        }
    });
    connect(ui->setEllipseLabColorBtn,&QPushButton::clicked,this,&MainWindow::onSetEllipseLabColorBtnClicked);
    connect(ui->setEllipseLabFontBtn,&QPushButton::clicked,this,&MainWindow::onSetEllipseLabFontBtnClicked);
    connect(ui->formatYRadioBtn,&QRadioButton::clicked,this,&MainWindow::onFormatYRadioBtnClicked);
    connect(ui->formatXYRadioBtn,&QRadioButton::clicked,this,&MainWindow::onFormatXYRadioBtnClicked);

    // 第三个工具栏
    connect(ui->axisXRadioBtn,&QRadioButton::clicked,this,&MainWindow::onAxisXRadioBtnClicked);
    connect(ui->axisYRadioBtn,&QRadioButton::clicked,this,&MainWindow::onAxisYRadioBtnClicked);
    connect(ui->axisIsVisiable,&QCheckBox::clicked,this,&MainWindow::onaxisIsVisiableChecked);
    connect(ui->setAxisRange,&QPushButton::clicked,this,&MainWindow::onSetAxisRangeClicked);
    connect(ui->isTitleVisible,&QCheckBox::clicked,this,&MainWindow::onIsTitleVisibleChecked);
    connect(ui->setAxisTitleBtn,&QPushButton::clicked,this,&MainWindow::onSetAxisTitleBtnClicked);
    connect(ui->setAxisFontBtn,&QPushButton::clicked,this,&MainWindow::onSetAxisFontBtnClicked);
    connect(ui->setAxisLabFontBtn,&QPushButton::clicked,this,&MainWindow::onSetAxisLabFontBtnClicked);
    connect(ui->setAxisLabFormatBtn,&QPushButton::clicked,this,&MainWindow::onSetAxisLabFormatClicked);
    connect(ui->setAxisLabColorBtn,&QPushButton::clicked,this,&MainWindow::onSetAxisLabColorBtnClicked);
    connect(ui->isLabelVisible,&QCheckBox::clicked,this,&MainWindow::onIsLabelVisibleChecked);

    // 第四个工具栏
    connect(ui->isGridLineVisible,&QCheckBox::clicked,this,&MainWindow::onIsGridLineVisibleChecked);
    connect(ui->setGridLineColorBtn,&QPushButton::clicked,this,&MainWindow::onSetGridLineColorBtnClicked);
    connect(ui->setGridLinePenBtn,&QPushButton::clicked,this,&MainWindow::onSetGridLinePenBtnClicked);
    // 主、次刻度线的spinbox改变
    using TickSpinBoxValueChanged = void(QSpinBox::*)(int);
    TickSpinBoxValueChanged valueChanged = &QSpinBox::valueChanged;
    connect(ui->tickSpinBox,valueChanged,this,&MainWindow::onTickSpinBoxChanged);
    using MinorTickSpinBoxChanged = void(QSpinBox::*)(int);
    MinorTickSpinBoxChanged minorSpinBoxChanged = &QSpinBox::valueChanged;
    connect(ui->minorTickSpinBox,minorSpinBoxChanged,this,&MainWindow::onMinorTickSpinBoxChanged);
    connect(ui->isLineVisible,&QCheckBox::clicked,this,&MainWindow::onIsLineVisibleChecked);
    connect(ui->setLinePenColorBtn,&QPushButton::clicked,this,&MainWindow::onSetLinePenColorBtnClicked);
    connect(ui->setLinePenBtn,&QPushButton::clicked,this,&MainWindow::onSetLinePenBtnClicked);
    connect(ui->setMinorGridLinePenBtn,&QPushButton::clicked,this,&MainWindow::onSetMinorGridLinePenBtnClicked);
    connect(ui->setMinorGridLineColorBtn,&QPushButton::clicked,this,&MainWindow::onSetMinorGridLineColorBtnClicked);
    connect(ui->isMinorGridLineVisible,&QCheckBox::clicked,this,&MainWindow::onIsMinorGridLineVisibleChecked);
}

void MainWindow::createChart()
{
    // 创建chart
    QChart* chart = new QChart();
    chart->setTitle("简单函数曲线");
    ui->chartView->setChart(chart);
    ui->chartView->setRenderHint(QPainter::Antialiasing);

    // 创建折线
    QLineSeries* series0 = new QLineSeries();
    QLineSeries* series1 = new QLineSeries();
    series0->setName("Sin曲线");
    series1->setName("Cos曲线");
    curSeries = series0; // 当前序列

    // 折线设置线条
    QPen pen;
    pen.setWidth(3);
    pen.setColor(Qt::red);
    pen.setStyle(Qt::SolidLine);
    series0->setPen(pen);
    pen.setColor(Qt::blue);
    pen.setStyle(Qt::DotLine);
    series1->setPen(pen);

    // chart添加折线
    chart->addSeries(series0);
    chart->addSeries(series1);

    // 创建坐标系
    QValueAxis* axisX = new QValueAxis();
    curAxis = axisX;
    axisX->setRange(0,100); // 设置坐标轴范围
    axisX->setLabelFormat("%.1f"); // 标签格式
    axisX->setTickCount(11); // 主分隔个数
    axisX->setMinorTickCount(4); // ???
    axisX->setTitleText("time(secs)"); // 标题
    QValueAxis* axisY = new QValueAxis();
    axisY->setRange(-2,2);
    axisY->setLabelFormat("%.2f");
    axisY->setTitleText("value");
    axisY->setTickCount(5);
    axisY->setMinorTickCount(4);

    // chart为series设置坐标系
    chart->setAxisX(axisX,series0);
    chart->setAxisY(axisY,series0);
    chart->setAxisX(axisX,series1);
    chart->setAxisY(axisY,series1);
}

void MainWindow::prepareData()
{
    // 为序列生成数据
    QLineSeries* series0 = (QLineSeries*)ui->chartView->chart()->series().at(0); // 获取series
    QLineSeries* series1 = (QLineSeries*)ui->chartView->chart()->series().at(1);
    series0->clear();
    series1->clear();
    qsrand(QTime::currentTime().second()); // 随机数初始化
    qreal t=0,y1,y2,intv=0.1;
    qreal rd;
    int cnt = 1000;
    for(int i=0;i<cnt;++i){
        rd = (qrand()%10)-5; // 随机数 -5~+5
        y1 = qSin(t)+rd/50;
        series0->append(t,y1); // series添加数据
        y2 = qCos(t)+rd/50;
        series1->append(t,y2); // series添加数据
        t+=intv;
    }
}

void MainWindow::updateFromChar()
{
    QChart* aChart = ui->chartView->chart(); // 获取chart
    ui->editTitle->setText(aChart->title()); // 图表标题
    QMargins mg = aChart->margins(); // 获取边距
    ui->spinMarginLeft->setValue(mg.left());
    ui->spinMarginRight->setValue(mg.right());
    ui->spinMarginTop->setValue(mg.top());
    ui->spinMarginBottom->setValue(mg.bottom());
}

void MainWindow::onLegendFontBtnClicked()
{
    bool ok = false;
    QLegend* legend = ui->chartView->chart()->legend();
    QFont legendFont = legend->font();
    QFont font = QFontDialog::getFont(&ok,legendFont);
    if(ok){
        legend->setFont(font);
    }
}

void MainWindow::onLegendColorBtnClicked()
{
    QLegend* legend = ui->chartView->chart()->legend();
    QColor legendColor = legend->color();
    QColor color = QColorDialog::getColor(legendColor);
    legend->setLabelColor(color);
}

void MainWindow::onSetMarginBtnClicked()
{
    int left = ui->spinMarginLeft->value();
    int right = ui->spinMarginRight->value();
    int top = ui->spinMarginTop->value();
    int bottom = ui->spinMarginBottom->value();
    QChart* chart = ui->chartView->chart();
    chart->setMargins(QMargins{left,top,right,bottom});
}

void MainWindow::onaxisIsVisiableChecked(bool isChecked)
{
    this->curAxis->setVisible(isChecked);
}

void MainWindow::onEllipseSinRadioBtnClicked()
{
    if(ui->ellipseSinRadioBtn->isChecked()){
        curSeries = (QLineSeries*)ui->chartView->chart()->series().at(0);
    }else{
        curSeries = (QLineSeries*)ui->chartView->chart()->series().at(1);
    }
    ui->seriesNameEdit->setText(curSeries->name());
    ui->seriesVisiable->setChecked(curSeries->isVisible());
    ui->seriesDataPointVisiable->setChecked(curSeries->pointsVisible());
    ui->opacitySlider->setValue(curSeries->opacity()*100);
    ui->seriesDataPointVisiable->setChecked(curSeries->pointsVisible());
    ui->dataPointLabVisiable->setChecked(curSeries->pointLabelsVisible());
    if(curSeries->pointLabelsFormat() == "@yPoint"){
        ui->formatYRadioBtn->setChecked(true);
    }else{
        ui->formatXYRadioBtn->setChecked(true);
    }
}

void MainWindow::onEllipseCosRadioBtnClicked()
{
    if(ui->ellipseCosRadioBtn->isChecked()){
        curSeries = (QLineSeries*)ui->chartView->chart()->series().at(1);
    }else{
        curSeries = (QLineSeries*)ui->chartView->chart()->series().at(0);
    }
    ui->seriesNameEdit->setText(curSeries->name());
    ui->seriesVisiable->setChecked(curSeries->isVisible());
    ui->seriesDataPointVisiable->setChecked(curSeries->pointsVisible());
    ui->opacitySlider->setValue(curSeries->opacity()*100);
    ui->seriesDataPointVisiable->setChecked(curSeries->pointsVisible());
    ui->dataPointLabVisiable->setChecked(curSeries->pointLabelsVisible());
    if(curSeries->pointLabelsFormat() == "@yPoint"){
        ui->formatYRadioBtn->setChecked(true);
    }else{
        ui->formatXYRadioBtn->setChecked(true);
    }
}

void MainWindow::onSetSeriesNameBtnClicked()
{
    if(curSeries!=nullptr){
        QString seriesName = ui->seriesNameEdit->text();
        curSeries->setName(seriesName);
    }
}

void MainWindow::onSeriesVisiableChecked(bool isChecked)
{
    if(curSeries!=nullptr){
        curSeries->setVisible(isChecked);
    }
}

void MainWindow::onSeriesDataPointVisiableChecked(bool isChecked)
{
    if(curSeries!=nullptr){
        curSeries->setPointsVisible(isChecked);
    }
}

void MainWindow::onDataPointLabVisiableChecked(bool isChecked)
{
    if(curSeries!=nullptr){
        curSeries->setPointLabelsVisible(isChecked);
    }
}

void MainWindow::onSetEllipseColorBtnClicked()
{
    if(curSeries!=nullptr){
        QColor seriesColor = curSeries->color();
        QColor color = QColorDialog::getColor(seriesColor);
        curSeries->setColor(color);
    }
}

void MainWindow::onSetEllipseLabColorBtnClicked()
{
    if(curSeries!=nullptr){
        QColor labColor = curSeries->pointLabelsColor();
        QColor color = QColorDialog::getColor(labColor);
        curSeries->setPointLabelsColor(color);
    }
}

void MainWindow::onSetEllipseLabFontBtnClicked()
{
    if(curSeries!=nullptr){
       QFont labFont = curSeries->pointLabelsFont();
       bool ok;
       QFont font = QFontDialog::getFont(&ok,labFont);
       curSeries->setPointLabelsFont(font);
    }
}

void MainWindow::onFormatYRadioBtnClicked()
{
    if(curSeries!=nullptr){
        QString format = ui->formatYRadioBtn->text();
        curSeries->setPointLabelsFormat(format);
    }
}

void MainWindow::onFormatXYRadioBtnClicked()
{
    if(curSeries!=nullptr){
        QString format = ui->formatXYRadioBtn->text();
        curSeries->setPointLabelsFormat(format);
    }
}

void MainWindow::onAxisXRadioBtnClicked()
{
    // 获取当前坐标轴
    if(ui->axisXRadioBtn->isChecked()){
        curAxis = (QValueAxis*)ui->chartView->chart()->axisX();
    }else{
        curAxis = (QValueAxis*)ui->chartView->chart()->axisY();
    }
    // 获取各种属性，并显示到界面上
    showAxisValue(curAxis);
}

void MainWindow::onAxisYRadioBtnClicked()
{
    // 获取当前坐标轴
    if(ui->axisYRadioBtn->isChecked()){
        curAxis = (QValueAxis*)ui->chartView->chart()->axisY();
    }else{
        curAxis = (QValueAxis*)ui->chartView->chart()->axisX();
    }
    // 获取各种属性，并显示到界面上
    showAxisValue(curAxis);
}

void MainWindow::onSetAxisRangeClicked()
{
    if(this->curSeries!=nullptr){
        double minVal = ui->minAxisSpinBox->value();
        double maxVal = ui->maxAxisSpinBox->value();
        if(ui->axisXRadioBtn->isChecked()){
            curAxis = (QValueAxis*)ui->chartView->chart()->axisX();
        }else{
            curAxis = (QValueAxis*)ui->chartView->chart()->axisY();
        }
        curAxis->setRange(minVal,maxVal);
    }
}

void MainWindow::onIsTitleVisibleChecked(bool isChecked)
{
    if(curAxis!=nullptr){
        curAxis->titleVisibleChanged(isChecked);
    }
}

void MainWindow::onSetAxisTitleBtnClicked()
{
    if(curAxis!=nullptr){
        QString title = ui->axisTitleEdit->text();
        curAxis->setTitleText(title);
    }
}

void MainWindow::onSetAxisFontBtnClicked()
{
    if(curAxis!=nullptr){
        QFont axisFont = curAxis->titleFont();
        bool ok;
        QFont font = QFontDialog::getFont(&ok,axisFont);
        curAxis->titleFontChanged(font);
    }
}

void MainWindow::onSetAxisLabColorBtnClicked()
{
    if(curAxis!=nullptr){
        QColor labColor = curAxis->labelsColor();
        QColor color = QColorDialog::getColor(labColor);
        curAxis->setLabelsColor(color);
        ui->chartView->chart()->update();
    }
}

void MainWindow::onSetAxisLabFormatClicked()
{
    if(curAxis!=nullptr){
//        QString labFormat = curAxis->labelFormat();
        QString format = ui->axisLabFormatEdit->text();
        qDebug() << format;
        curAxis->setLabelFormat(format);
        ui->chartView->chart()->update();
    }
}

void MainWindow::onSetAxisLabFontBtnClicked()
{
    if(curAxis!=nullptr){
        QFont labFont = curAxis->labelsFont();
        bool ok;
        QFont font = QFontDialog::getFont(&ok,labFont);
//        curAxis->labelsFontChanged(font);
        curAxis->setLabelsFont(font);
    }
}

void MainWindow::onIsLabelVisibleChecked(bool isChecked)
{
    if(curAxis!=nullptr){
        curAxis->labelsVisibleChanged(isChecked);
    }
}

void MainWindow::onIsGridLineVisibleChecked(bool isChecked)
{
    if(curAxis!=nullptr){
        curAxis->setGridLineVisible(isChecked);
    }
}

void MainWindow::onSetGridLineColorBtnClicked()
{
    if(curAxis!=nullptr){
        QColor gridLineColor = curAxis->gridLineColor();
        QColor color = QColorDialog::getColor(gridLineColor);
        curAxis->setGridLineColor(color);
    }
}

void MainWindow::onSetGridLinePenBtnClicked()
{
    if(curAxis!=nullptr){
        QPen gridLinePen = curAxis->gridLinePen();
        this->curAxis->setGridLinePen(gridLinePen);
    }
}

void MainWindow::onTickSpinBoxChanged(int value)
{
    if(curAxis!=nullptr){
        curAxis->setTickCount(value);
    }
}

void MainWindow::onMinorTickSpinBoxChanged(int value)
{
    if(curAxis!=nullptr){
        curAxis->setMinorTickCount(value);
    }
}

void MainWindow::onSetMinorGridLineColorBtnClicked()
{
    if(curAxis!=nullptr){
        QColor minorColor = curAxis->minorGridLineColor();
        QColor color = QColorDialog::getColor(minorColor);
        curAxis->setMinorGridLineColor(color);
    }
}

void MainWindow::onSetMinorGridLinePenBtnClicked()
{
    if(curAxis!=nullptr){
        QPen minorPen = curAxis->minorGridLinePen();
        // 不知道这个pen是怎么设置或者说设置来干嘛的
        curAxis->setMinorGridLinePen(minorPen);
    }
}

void MainWindow::onIsMinorGridLineVisibleChecked(bool isChecked)
{
    if(curAxis!=nullptr){
        curAxis->setMinorGridLineVisible(isChecked);
    }
}

void MainWindow::onIsLineVisibleChecked(bool isChecked)
{
    if(curAxis!=nullptr){
        curAxis->setLineVisible(isChecked);
    }
}

void MainWindow::onSetLinePenColorBtnClicked()
{
    if(curAxis!=nullptr){
        QColor lineColor = curAxis->linePenColor();
        QColor color = QColorDialog::getColor(lineColor);
        curAxis->setLinePenColor(color);
    }
}

void MainWindow::onSetLinePenBtnClicked()
{
    if(curAxis!=nullptr){
        QPen pen = curAxis->linePen();
        // 不知道pen怎么用
        curAxis->setLinePen(pen);
    }
}


void MainWindow::showAxisValue(QValueAxis *axis)
{
    ui->minAxisSpinBox->setValue(axis->min());
    ui->maxAxisSpinBox->setValue(axis->max());
    ui->axisTitleEdit->setText(axis->titleText());
    ui->axisIsVisiable->setChecked(axis->isVisible());
    ui->axisLabFormatEdit->setText(axis->labelFormat());
    ui->isLabelVisible->setChecked(axis->labelsVisible());
    ui->isGridLineVisible->setChecked(axis->isGridLineVisible());
    ui->isLineVisible->setChecked(axis->isLineVisible());
    ui->tickSpinBox->setValue(axis->tickCount());
    ui->minorTickSpinBox->setValue(axis->minorTickCount());
    ui->isMinorGridLineVisible->setChecked(axis->isMinorGridLineVisible());
}

void MainWindow::onSetTitleBtnClicked()
{
    QString title =ui->editTitle->text();
    ui->chartView->chart()->setTitle(title);
}

void MainWindow::onSetTitleFontBtnClicked()
{
    QFont titleFont = ui->chartView->chart()->titleFont();
    bool ok;
    QFont font = QFontDialog::getFont(&ok,titleFont);
    if(ok){
        ui->chartView->chart()->setFont(font);
    }
}

void MainWindow::onLeftRadioBtnClicked()
{
    QLegend* legend = ui->chartView->chart()->legend();
    legend->setAlignment(Qt::AlignLeft);
}

void MainWindow::onRightRadioBtnClicked()
{
    QLegend* legend = ui->chartView->chart()->legend();
    legend->setAlignment(Qt::AlignRight);
}

void MainWindow::onTopRadioBtnClicked()
{
    QLegend* legend = ui->chartView->chart()->legend();
    legend->setAlignment(Qt::AlignTop);
}

void MainWindow::onBottomRadioBtnClicked()
{
    QLegend* legend = ui->chartView->chart()->legend();
    legend->setAlignment(Qt::AlignBottom);
}

void MainWindow::onLegendVisiableCheck(bool isChecked)
{
    ui->chartView->chart()->legend()->setVisible(isChecked);
}

void MainWindow::onBackgroundVisiableCheck(bool isChecked)
{
    ui->chartView->chart()->legend()->setBackgroundVisible(isChecked);
}


MainWindow::~MainWindow()
{
    delete ui;
}
